/*-------------------------------------------------------------------------

***************** Modification History ***********************************
   @doc
   @module dp3101.c - Functions to Control DataPac 3101 communications |
   @end
   
$Log: /SoftPay/SPK2SIM/Source/Comm/dp3101.c $ 
**************************************************************************

   Copyright (C) 1999 by VeriFone, Inc.

   All rights reserved.  No part of this software may be reproduced,
   transmitted, transcribed, stored in a retrieval system, or translated
   into any language or computer language, in any form or by any means,
   electronic, mechanical, magnetic, optical, chemical, manual or otherwise,
   without the prior written permission of VeriFone, Inc.

---------------------------------------------------------------------------*/
#include <project.h>

#ifdef DP3101_DEFINED

#define VSDP3101_C

#include <stdio.h>
#include <xmodem.h>
#include <acldev.h>
#include <ascii.h>
#include <string.h>

#ifdef DEBUG_VSDP3101
#define DEBUG_95
#endif

#include <define.h>
#include <comm.h>
#include <modem.h>
#include <modemmsg.h>
#include <spdebug.h>
#include <init.h>
#include <msgfuncs.h>
#include <packet.h>
#include <dp3101.h>

/*-------------------------------------------------------------------------
    Function : inRecvUntilChar ()
    Description : Reads one character at a time unitl the stop character
                  is read. The characters read are saved in a buffer.
    Returns
    Parameters :
    Returns :
    Globals :
    Notes :
    Modification History :
      #     Date      Who                     Description
    ----- -------- ---------- ---------------------------------------------
      1   09/23/98 Monique_B1  Modified for North American SoftPay Base
--------------------------------------------------------------------------*/

int inRecvUntilChar(unsigned char* str,unsigned char untilCh,int inTimeOut,short inMaxLen,int hModem) {
    short shLen;
    unsigned long   ulTicks;
    char stDummy[1];

    shLen = 0;
    ulTicks = set_itimeout(NO_CLOCK_HANDLE(unsigned int) inTimeOut, TM_SECONDS);
    do {
        if (CHECK_TIMEOUT(ulTicks) == 0)
            return(VS_ERR);
        if (read(hModem, stDummy, 1) != 1)
            continue;
        *str++ = stDummy[0];
        if (++shLen >= inMaxLen)         /*gv added 8/30/96 */
            return(VS_ERR);
        if (stDummy[0] == untilCh)
            break;
    } while (1);
    return(VS_SUCCESS);
}

/*-------------------------------------------------------------------------
    Function : inCheck3101()
    Description : Checks after the communication link has been established
                  the Datapac 3101.
    * This is an overview of the link to the local datapac circuit and
    * then to NCR EFT
    *
    * dial the datapac local number and send ".CR"
    * datapac will return with LF followed with a datapac address
    * send PROF 6 CR
    * datapac will return with LF
    * Send the NCR datapac host address
    ********* From this point the messages are from NCR EFT **********
    * NCR will send ENQ
    * Send the message
    * NCR will send a response
    * Wait for 1 second and disconnect

    Parameters :
    Returns :   VS_ERR VS_SUCCESS
    Globals :
    Notes :
    Modification History :
      #     Date      Who                     Description
    ----- -------- ---------- ---------------------------------------------
      1   08/18/95  George_V1 Creation.
      2   10/08/96 Jose_F1    Added CONNECTING3101 MSG=113
      3   09/23/98 Monique_B1 Modified for North American SoftPay Base
      4   01/29/99 Page_K1    Leave '\r' out of COMM_3101_CHK_MSG and send CR.
                              Add obModem->hModem parameter to inRecvUntilChar() call.
      5   02/19/99 Betty_B1   Remove display of CONNECTING_3101 message.
                              It did not display long enough to be read.
                              DFW 206
      
-------------------------------------------------------------------------*/

int inCheck3101(COMM_OBJECT* obCommunication) {
    int inStatus,
    inStrLen;
    char szDatapac[8];
    char szResp[128];
    char stProf6[8];
    MODEM_OBJECT* obModem;
    char szHostAddr[DP3101_HOST_ADDR_SIZE + 1];

    pdebug(("--inCheck3101--"));

    obModem = (MODEM_OBJECT *) obCommunication->Data;

    /*-----------------5/30/96 11:18AM------------------
     For multiple message flag
    --------------------------------------------------*/

    vdGetMessageFromFile(COMM_3101_CHK, stProf6);

    SVC_WAIT(1000);
    inSendChar(0x2E); /* Send a period */ 

    inSendChar(CR);
    pdebug(("inCheck3101 (.) and (CR) sent"));

    /* Now read everything until a CR is received. We are expecting
     a response of DATAPAC: XXXX XXXX CR */

    inStatus = inRecvUntilChar((unsigned char *) szResp, CR, 30, sizeof(szResp), obModem->hModem);
    xmdm_flush(obModem->hModem);

    if (inStatus == VS_ERR)
        return (VS_ERR);

    vdGetMessageFromFile(DATAPAC, szDatapac);

    if (strncmp(szResp, szDatapac, 7) != 0)
        return (VS_ERR);

    pdebug(("inCheck3101 we got (DATAPAC)"));

    /* vdDisplayMessageFromFile( CONNECTING_3101, STATUS_MSG); */

    /* Tx PROF 6 string                               */
    xmdm_flush(obModem->hModem);
    inStrLen = strlen(stProf6);

    if (write(obModem->hModem, stProf6, inStrLen) != inStrLen)
        return (VS_ERR);
    pdebug(("inCheck3101 we sent (PROF6)"));
    inSendChar(CR);

    if (inRecvUntilChar((unsigned char *) szResp, LF, 45, sizeof(szResp), obModem->hModem) == VS_ERR)
        return (VS_ERR);

    xmdm_flush(obModem->hModem);
    SVC_WAIT(1000);

    obModem->vdGet3101HostAddr(szHostAddr, obModem->srCPT);
    inStrLen = strlen(szHostAddr);
    if (write(obModem->hModem, szHostAddr, inStrLen) != inStrLen)
        return (VS_ERR);
    inSendChar(CR);

    pdebug(("inCheck3101 we sent Host Addr and CR"));

    obCommunication->fLinkUp = VS_TRUE;

    return (VS_SUCCESS);
}

/*-------------------------------------------------------------------------
    Function : inCheckModem3101Communication()
    Description : Checks whether the communication link has been established.
                  Then Checks if the communication link has been established
                  on the Datapac 3101.
    Returns
    Parameters :
    Returns :
    Globals :
    Notes :
    Modification History :
      #     Date      Who                     Description
    ----- -------- ---------- ---------------------------------------------
      1   09/23/98 Monique_B1       Creation.
--------------------------------------------------------------------------*/
int inCheckModem3101Communication(COMM_OBJECT* obCommunication) {
    int inResult;
    MODEM_OBJECT* obModem;

    pdebug(("--inCheckModem3101Communication--"));

    obModem = (MODEM_OBJECT *) obCommunication->Data;


    if ((inResult = inCheckModemCommunication(obCommunication)) != VS_SUCCESS)
        return (inResult);

    if (obModem->fGet3101CommType(obModem->srCPT) == (VS_BOOL) PUBLIC_3101)
        inResult = inCheck3101(obCommunication);

    return (inResult);
}
/*-------------------------------------------------------------------------
    Function : vdInitialize3101PrivateComm()
    Description :
    Parameters :
    Returns :
    Globals :
    Notes :
    Modification History :
      #     Date      Who                     Description
    ----- -------- ---------- ---------------------------------------------
      1   09/23/98 Monique_B1   Creation.
--------------------------------------------------------------------------*/

void vdInitialize3101Comm(COMM_OBJECT* obCommunication) {
    /** /pdebug(("--vdInitialize3101PrivateComm--"));*/
    obCommunication->inLinkType = COMM_3101; /* DataPac 3101 PROTOCOL */
    obCommunication->fLinkUp = VS_FALSE;
    obCommunication->inInitialize = (PFI_VD) inInitModemCommunication;
    obCommunication->inBegin = (PFI_PFOR_BEGIN) inBeginModemCommunication;
    obCommunication->inCheck = (PFI_VD) inCheckModem3101Communication;
    obCommunication->inSend = (PFI_PFOR_SEND) inSendModemCommunication;
    obCommunication->inReceive = (PFI_PFOR_RES) inReceiveModemCommunication;
    obCommunication->inEnd = (PFI_VD) inEndModemCommunication;
    obCommunication->inFlush = (PFI_VOID) inFlushModemCommunication;
    obCommunication->inDeinitialize = (PFI_VD) inDeInitModemCommunication;
    return;
} /* End of vdInitialize3101Comm() */

#undef VSDP3101_C

#endif  //DP3101_DEFINED

